package com.ap.core.bulkupload.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.Validator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;

import com.ap.core.bulkupload.resource.ResourceLocation;
import com.ap.core.bulkupload.service.SchemaValidationService;
import com.ap.core.bulkupload.types.BulkFileUploadEnum;
import com.ap.core.bulkupload.validation.info.ValidationInfo;
import com.ap.core.bulkupload.validation.info.ValidationResult;
import com.ap.core.exception.APCoreException;

/**
 * User: Gibu.Paul
 * 
 * Implementation class for {@link DefaultSchemaValidationServiceImpl}
 */
public class DefaultSchemaValidationServiceImpl implements SchemaValidationService<Object> {

	/** The log. */
	private static final Logger LOG = LoggerFactory
			.getLogger(DefaultSchemaValidationServiceImpl.class);
	
	/** The resource. */
	private final Map<BulkFileUploadEnum, ResourceLocation> resource;

	/**
	 * Instantiates a new default schema validation service impl.
	 *
	 * @param resource the resource
	 */
	public DefaultSchemaValidationServiceImpl(
			Map<BulkFileUploadEnum, ResourceLocation> resource) {
		this.resource = resource;
	}

	/**
	 * Validate.
	 *
	 * @param bulkValidationType the bulk validation type
	 * @return ValidationInfo
	 */
	@Override
	public ValidationResult validate(BulkFileUploadEnum bulkValidationType, InputStream inputStream) throws APCoreException{
		String methodName = "validate() - ";
		final List<ValidationInfo> failedSchemaList = new ArrayList<ValidationInfo>();
		Validator validator = null;
		Source xmlSource = null;
		Schema schema = null;		
		try {
			schema = resource.get(bulkValidationType).getSchema();
			xmlSource = new StreamSource(inputStream);
			validator = schema.newValidator();
			validator.validate(xmlSource);
			LOG.info(methodName + "Schema validated successfully for ["+bulkValidationType +"]");
		} catch (IOException ioe) {
			LOG.error(methodName + "IOException occurred for ["+bulkValidationType +"] and Error ["+Arrays.toString(ioe.getStackTrace())+"]");
			failedSchemaList.add(populateError(bulkValidationType, ioe));
		} catch (SAXException saxe) {
			LOG.error(methodName + "SAXException occurred for ["+bulkValidationType +"] and Error ["+Arrays.toString(saxe.getStackTrace())+"]");
			failedSchemaList.add(populateError(bulkValidationType, saxe));
		} catch (Exception ex) {
			LOG.error(methodName + "Exception occurred for ["+bulkValidationType +"] and Error ["+Arrays.toString(ex.getStackTrace())+"]");
			throw new APCoreException(ex);
		}
		return new 	ValidationResult(failedSchemaList);
	}
	
	/**
	 * Populate error.
	 *
	 * @param bulkFileUploadEnum the bulk file upload enum
	 * @param th the th
	 * @return the validation info
	 */
	private ValidationInfo populateError(BulkFileUploadEnum bulkFileUploadEnum, Throwable th) {
		
		
		ValidationInfo validationInfo = new ValidationInfo(bulkFileUploadEnum.toString()+"001");
		/*failedRuInfo.add(new ValidationInfo(rule.getRuleId(), rule
				.getErrorCode(), rule.getRuleDescription()));*/
		
		/*ValidationInfo validationInfo = new ValidationInfo(BulkFileUploadConstants.SCHEMA_VALIDATION_RULE, 
				bulkFileUploadEnum.toString()+"001", th.getMessage());*/
		return validationInfo;
	}

}
